//
// Created by HhL on 2021/7/7.
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "../../include/c_utils.h"

void function_pointer_test();

void stu_test();

void byte_align_test();

void byte_align_p_test();

void int_array_test();

void null_memory_test();

void pointer_constants_and_constant_pointers();

const int MAX = 3;

/**
 * 指针函数: 返回指针的函数
 * 函数指针：指向函数的指针变量,一个用指针表示的函数
 */
int max(int x, int y) {
    return x > y ? x : y;
}

void function_pointer_test() {
    int (* p)(int, int) = max;
    int a = 0, b = 1;
    printf("max：%d\n", max(a, b));
    printf("*p：%d\n", p(a, b));
}

struct Student {
    char name[20];
//    int age;
//    int level;
} s, * ps;

struct Student1 {
    char name[20];
    int age:16;
    int level:16;
} s1, * ps1;
struct A {
    char c1;
    char c2;
    int i;
} a, * pa;

struct B {
    char c1;
    int i;
    char c2;
} b, * pb;


int main() {
//    char abc[] = "hello world";
//
//    int ret = mystrlen2(abc);  // 实际参数 abc
//
//    printf("ret = %d\n", ret);
//    stu_test();
    //函数指针测试
//    function_pointer_test();
//字节对齐规则 4字节对齐，小的永远一起放到最上部分
//    byte_align_test();
//    byte_align_p_test();
//    int_array_test();
//    null_memory_test();

//    pointer_constants_and_constant_pointers();

//申请堆空间？
    int* p = (int*) malloc(sizeof(int) * 10);
    //char *str = (char *)malloc(sizeof(char)*10);
    if (p == NULL) {
        printf("malloc error\n");
        return -1;
    }
    char* tmp = p;  // 记录malloc返回的地址值。用于free

    // 写数据到 malloc 空间。
    for (size_t i = 0; i < 10; i++) {
        p[i] = i + 10;
    }
    // 读出malloc空间中的数据
    //for (size_t i = 0; i < 10; i++)
    //{
    //	printf("%d ", *(p+i));
    //}
    for (size_t i = 0; i < 10; i++) {
        printf("%d ", *p);
        p++;
    }

    // 释放申请的内存。
    free(tmp);
    p = NULL;

    system("pause");
    return 0;
}


/**
 * 指针常量 指针指向常量 可变 *在const后
 * 常量指针 重点在常量  *在const前  不可修改
 */
void pointer_constants_and_constant_pointers() {
    int i = 11111;
    int h = 222;
    int const* p = &i;//常量指针 可以再赋值
//    printf("%d\n", p);
    p = &h;
    printf("%d\n", *p);
    int* const p1 = &i;// 指针常量
    printf("%d\n", *p1);
//    p1 = &h;//不可再赋值
    const int* const p3 = &i;
    printf("%d\n", *p3);
//    p3=&h; 不可再赋值
}

void null_memory_test() {
    int m;
    int* p = &m;
    printf("%d\n", *p);
}

void int_array_test() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7};
    // 计算出数组元素个数
    int len = sizeof(arr) / sizeof(int);
    int des[len];
    // 反向赋值
    for (int i = 0; i < len; ++i) {
        *(des + len - 1 - i) = *(arr + i);
    }
    // 遍历输出
    for (int i = 0; i < len; ++i) {
        printf("%d\n", *(des + i));
    }
}

/**
 * & 取地址符
* 两个作用：定义指针、解引用
 */
void byte_align_p_test() {
//    int c = 10;
//    int* p = &c;
//    int** pp = &p;
//    int* h = *pp;
//    printf(" c：%d, p：%d, pp：%d, *p：%d ,*h:%d\n", c, p, pp, *p, *h);

//    int m = 10;
//    int* p = &m;
//    (*p)++;
//
//    int* pp = (int*) 10;
//    printf(" pp：%d\n", pp);
//    printf(" m：%d, pm :%d\n", m, *p);
//    p++;
//    printf(" *p：%d\n", p);

//    int var[] = {10, 100, 200};
//    int i, * ptr;
//
//    /* 指针中的数组地址 */
//    ptr = var;
//    for (i = 0; i < MAX; i++) {
//        printf("存储地址：var[%d] = %p\n", i, ptr);
//        printf("存储值：var[%d] = %d\n", i, *ptr);
//
//        /* 指向下一个位置 */
//        ptr++;
//    }
//    char c[] = "0123456789";//0 asc码 48
//
//    int* ptr = (int*) c;
//    char* cp = c;
//    printf("%d\t%d\n", sizeof(int), sizeof(char));
//    printf("cp:%d\n", *cp); //指向头部第一个
//    while (*cp++ && (*cp != '\0')) {
//        printf("*cp++:%c\n", *cp);
//    }
//    printf("*ptr:%c\n", *(++ptr));// 指针往前移动了 int 宽度的字节，+4位置
//    printf("*ptr:%c\n", ++(*(ptr)));//*(ptr) 这个值+1
//
//    int arr[] = {1, 2, 3, 4, 5};
//    int* p1 = arr; //等价于 &arr[0]
//    int* p2 = &arr[1];
//    printf("p1:%d,p2:%d\n", *p1,*p2);
////    while (*p1++ && (*p1 != '\0')) {
////        printf("p1:%d\n", *p1);
////    }
//    printf("*p1:%d\n", *(++p1));
//    printf("*p2:%d\n", *(++p2));



//    int v = *(p + 1);// 10
//    int val = *p + 1; //2
//    printf("v:%d,val:%d\n", v,val);
//通过指针操作数组实现元素翻转
//    int len = sizeof(arr) / sizeof(int);
//    int p[len];
//    for (int i = 0; i < len ; ++i) {
//        *(p + len - i - 1) = *(arr + i);
//    }
    short arr[] = {1, 2, 3, 4, 5, 6, 7};


    // 计算出数组元素个数
    int len = sizeof(arr) / sizeof(short);
    short des[len];
    // 反向赋值
    for (int i = 0; i < len; ++i) {
        *(des + len - 1 - i) = *(arr + i);
    }

    // 遍历输出
    for (int i = 0; i < len; ++i) {
        printf("%d\n", *(des + i));
    }
}


void byte_align_test() {

//    printf(" B：%d\n", sizeof(struct B));
//    printf(" b：%d\n", sizeof(b));
//    printf(" *pb：%d\n", sizeof(*pb));
//    printf(" A：%d\n", sizeof(struct A));
//    printf(" a：%d\n", sizeof(a));
//
//    printf(" *pa：%d\n", sizeof(*pa));
//    a.i = 10;
//    printf(" *a.i %d\n", a.i);
    struct A a1;
    a1.i = 100;
    printf(" a.i %d\n", a1.i);
}

void stu_test() {
//    struct Student1 stu1;
////    printf("Hello,02.c \n");
//
//    printf("Student stu1：%d\n", sizeof(stu1));// 为毛是24？
//    printf("Student s1：%d\n", sizeof(s1));//Student1
//    printf("Student s1.name：%d\n", sizeof(s1.name));//20
//
//    printf("Student ps1：%d\n", sizeof(ps1));//指针是8？
//    printf("Student ps1->name：%d\n", sizeof(ps1->name));//20

//    printf("Student ps1->level：%d\n", ps1->level);//输出不了
}



